import Vue from "vue";
import Index from "./index.vue";
let NotificationConstructor = Vue.extend(Index);
let instance;
let instances = [];
let seed = 1;
const Notification = (option = {}) => {
  const _default_option = {
    visible: false,
    title:'',
    message: "",
    duration: 3000,
    type: "info",
    onClose: null,
    showClose: false,
    closed: false,
    position: "top-right",
    offset: 20,
    dangerouslyUseHTMLString: false,
    center: false,
  };
  const _option = Object.assign(_default_option, option);
  let userOnClose = _option.onClose;
  let id = "notification_" + seed++;
  const position = _option.position || 'top-right';

  _option.onClose = function () {
    Notification.close(id, userOnClose,position);
  };

  instance = new NotificationConstructor({
    data: _option,
  });
  instance.id = id;

  if (isVNode(instance.message)) {
    instance.$slots.default = [instance.message];
    instance.message = null;
  }
  instance.$mount();

  document.body.appendChild(instance.$el);

  let verticalOffset = _option.offset || 20;
  instances.filter(item => item.position === position).forEach(item => {
    verticalOffset += item.$el.offsetHeight + 16;
  });

  instance.verticalOffset = verticalOffset;
  instance.visible = true;

  instances.push(instance);
  return instance;
};

Notification.close = function (id, userOnClose,position) {
  let len = instances.length;
  let index = -1;
  let removedHeight;
  for (let i = 0; i < len; i++) {
    if (id === instances[i].id) {
      removedHeight = instances[i].$el.offsetHeight;
      index = i;
      if (typeof userOnClose === "function") {
        userOnClose(instances[i]);
      }
      instances.splice(i, 1);
      break;
    }
  }
  if (len <= 1 || index === -1 || index > instances.length - 1) return;
  for (let i = index; i < len - 1; i++) {
    let dom = instances[i].$el;
    let _position = position.indexOf('top') > -1 ? 'top':'bottom';
    dom.style[_position] =
      parseInt(dom.style[_position], 10) - removedHeight - 16 + "px";
  }
};

Notification.closeAll = function () {
  for (let i = instances.length - 1; i >= 0; i--) {
    instances[i].close();
  }
};

function isVNode(node) {
  return (
    node !== null &&
    typeof node === "object" &&
    hasOwn(node, "componentOptions")
  );
}

function hasOwn(obj, key) {
  return hasOwnProperty.call(obj, key);
}

export default Notification;
